﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Data.SqlServerCe;

namespace EventWatcher {
    public partial class Child : Form {
        List<string> content;
        bool keepAlive = true;
        Thread th;
        Thread autorefreshThread;
        DateTime startTime;
        DateTime stopTime;
        public string Machine { get; private set; }

        public Child(string machine) {
            InitializeComponent();
            if (System.Diagnostics.Debugger.IsAttached) {
                testButton.Visible = true;
            }

            content = new List<string>();
            startTime = DateTime.Now.AddHours(-2);
            stopTime = DateTime.Now;

            toolStripButton4_Click(this, new EventArgs());

            this.Machine = machine;
            th = new Thread(PreFetch);
            th.Start();
        }

        void PreFetch() {
            //here we'll put all the inital load info
            //it'll load the inital data, threadsafe then show the child
            //this will fix the lag issues w/ multi children loading :D
            CheckNow();

            //prefetch is done, show the form!
            PreFetchDone();
        }

        private delegate void UpdateTextboxDelegate(string value);
        void UpdateDisplay(string value) {
            if (InvokeRequired) {
                Invoke(new UpdateTextboxDelegate(UpdateDisplay), new object[] { value });
            } else {
                try {//really?
                    string newLine = value + Environment.NewLine;
                    if (!content.Contains(newLine)) {
                        content.Add(newLine);
                        ExternalLogging(newLine);
                        this.richTextBox1.AppendText(newLine);
                        this.richTextBox1.AppendText("----------------------------------------------------------" + Environment.NewLine + Environment.NewLine);
                    }
                } catch (Exception) { }//really?
            }
        }

        static object TheWorld = "Blam!";
        void ExternalLogging(string line) {
            lock (TheWorld) {
                using (System.IO.StreamWriter sw = new System.IO.StreamWriter("output.txt", true)) {
                    sw.WriteLine(Machine + "|" + line);
                }

                if (line.Contains("successfull") || line.Contains("failed")) {
                    using (System.IO.StreamWriter sw = new System.IO.StreamWriter("filteredOutput.txt", true)) {
                        sw.WriteLine(Machine + "|" + line);
                    }
                }
            }
        }


        void ExternalLogging_Bunk(string line) {
            //ToDo: Make an external logger...
            int affected = 0;
            //using (SqlCeConnection con = new SqlCeConnection(Properties.Settings.Default.DataStoreConnectionString)) {
            using (SqlCeConnection con = new SqlCeConnection()) {
                con.ConnectionString = "Persist Security Info=False; Data Source = DataStore.sdf;";
                
                con.Open();

                Console.WriteLine("ZOMG");

                //if this works...
                //ToDo: Update input args...
                string sql = string.Format("INSERT INTO records(machine, message) VALUES('thisone', 'that message')");
                using (SqlCeCommand cmd = new SqlCeCommand(sql, con)) {
                    while (affected == 0) {
                        affected = cmd.ExecuteNonQuery();
                        Console.WriteLine("Attempted insert!");
                        System.Threading.Thread.Sleep(20);//just in case?
                    }
                }
            }
        }

        void PreFetchDone() {
            if (InvokeRequired) {
                Invoke(new MethodInvoker(PreFetchDone));
            } else {
                Beans.Loaded++;
                this.Show();
            }
        }

        void CheckNow() {
            List<EventLogEntry> filtered = new List<EventLogEntry>();
            try {
                EventLog el = new EventLog("Application", Machine);
                EventLogEntryCollection col = el.Entries;
                foreach (EventLogEntry entry in col) {
                    if (entry.TimeGenerated >= startTime && entry.TimeGenerated <= stopTime) {
                        filtered.Add(entry);
                    }
                }
                //feed to the UI
                foreach (EventLogEntry item in filtered) {
                    string line = string.Format("{0} {1} {2}", item.TimeGenerated, item.Source, item.Message);
                    UpdateDisplay(line);
                }
            } catch (Exception) {
                UpdateDisplay("Unable to check machine at this time.");
            }

        }

        //private void toolStripButton1_Click(object sender, EventArgs e) {
        //    List<EventLogEntry> filtered = new List<EventLogEntry>();
        //    try {
        //        EventLog el = new EventLog("Application", Machine);
        //        EventLogEntryCollection col = el.Entries;
        //        foreach (EventLogEntry entry in col) {
        //            if (entry.TimeGenerated >= DateTime.Now.AddHours(-1) && entry.TimeGenerated <= DateTime.Now) {
        //                filtered.Add(entry);
        //            }
        //        }
        //        //feed to the UI
        //        foreach (EventLogEntry item in filtered) {
        //            string line = string.Format("{0} {1} {2}", item.TimeGenerated, item.Source, item.Message);
        //            UpdateDisplay(line);
        //        }
        //    } catch (Exception) {
        //        UpdateDisplay("Unable to check machine at this time.");
        //    }
        //}

        private void testButton_Click(object sender, EventArgs e) {
            EventLog el = new EventLog("Application");
            el.Source = "MsiInstaller";
            el.WriteEntry("This is a sample event!", EventLogEntryType.Information);
            Console.WriteLine("INJECTED");
        }

        //private void toolStripButton3_Click(object sender, EventArgs e) {
        //    List<EventLogEntry> filtered = new List<EventLogEntry>();
        //    try {
        //        EventLog el = new EventLog("Application", Machine);
        //        EventLogEntryCollection col = el.Entries;
        //        foreach (EventLogEntry entry in col) {
        //            if (entry.TimeGenerated >= DateTime.Now.AddHours(-24) && entry.TimeGenerated <= DateTime.Now) {
        //                filtered.Add(entry);
        //            }
        //        }
        //        //feed to the UI
        //        foreach (EventLogEntry item in filtered) {
        //            string line = string.Format("{0} {1} {2}", item.TimeGenerated, item.Source, item.Message);
        //            UpdateDisplay(line);
        //        }
        //    } catch (Exception) {
        //        UpdateDisplay("Unable to check machine at this time.");
        //    }
        //}

        private void toolStripButton4_Click(object sender, EventArgs e) {
            if (toolStripButton4.Checked) {
                keepAlive = true;
                autorefreshThread = new Thread(ThreadedRefresh);
                autorefreshThread.Start();
            } else {
                keepAlive = false;
            }
        }

        protected override void OnClosing(CancelEventArgs e) {
            keepAlive = false;
            base.OnClosing(e);
        }

        void ThreadedRefresh() {
            //toggle switch controlled...
            int i = 0;
            while (keepAlive) {
                List<EventLogEntry> filtered = new List<EventLogEntry>();
                try {
                    EventLog el = new EventLog("Application", Machine);
                    EventLogEntryCollection col = el.Entries;
                    foreach (EventLogEntry entry in col) {
                        if (entry.TimeGenerated >= DateTime.Now.AddHours(-1) && entry.TimeGenerated <= DateTime.Now) {
                            filtered.Add(entry);
                        }
                    }
                    //feed to the UI
                    foreach (EventLogEntry item in filtered) {
                        string line = string.Format("{0} {1} {2}", item.TimeGenerated, item.Source, item.Message);                        
                        UpdateDisplay(line);
                    }
                } catch (Exception) {
                    UpdateDisplay("Unable to check machine at this time.");
                }

                Console.WriteLine("BLAM! {0}", ++i);                
                Thread.Sleep(5000);
            }
        }

    }



}
